package cn.demo.weixin.ma.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.demo.common.core.domain.model.LoginUser;
import cn.demo.common.core.domain.model.UserInfo;
import cn.demo.common.core.redis.RedisCache;
import cn.demo.common.exception.ServiceException;
import cn.demo.common.utils.bean.BeanUtils;
import cn.demo.um.domain.UmClientUser;
import cn.demo.um.mapper.UmClientUserMapper;
import cn.demo.weixin.ma.config.WxMaConfig;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Service;

import java.util.UUID;

import static cn.demo.um.domain.table.UmClientUserTableDef.UM_CLIENT_USER;

@Service
@Slf4j
public class WxMaLoginService {
    @Resource
    private RedisCache redisCache;
    @Resource
    private UmClientUserMapper clientUserMapper;

    public LoginUser wxmaLogin(String appId, String code) {
        WxMaJscode2SessionResult jscode2session = null;
        try {
            jscode2session = WxMaConfig.getMaService(appId).jsCode2SessionInfo(code);
        } catch (WxErrorException e) {
            log.error("微信授权登录失败！{}", e.getMessage());
        }
        if (null == jscode2session) {
            throw new ServiceException("登录失败！");
        }

        String openId = jscode2session.getOpenid();
        String unionId = jscode2session.getUnionid();

        String uuid = UUID.randomUUID().toString();
        String lock = "lock:wxmaLogin:" + openId;
        try {
            if (redisCache.lockWait(lock, uuid)) {

                UmClientUser clientUser = clientUserMapper.selectOneByQuery(QueryWrapper.create().and(UM_CLIENT_USER.WXMA_OPENID.eq(openId).or(UM_CLIENT_USER.WX_UNIONID.eq(unionId))));

                if (null == clientUser) {
                    clientUser = new UmClientUser();
                    clientUser.setWxmaOpenid(openId);
                    clientUser.setWxUnionid(unionId);
                    clientUser.setStatus(0);
                    clientUser.setAuthStatus(0);
                    clientUser.setIntegral(0L);
                    clientUser.setIntegralTotal(0L);
                    clientUser.setIntegralUsed(0L);
                    clientUser.setIsShow(0);
                    clientUserMapper.insert(clientUser);
                } else {
                }

                LoginUser loginUser = new LoginUser();
                loginUser.setUserId(clientUser.getId());
                loginUser.setUserInfo(BeanUtils.copy(clientUser, UserInfo.class));
                return loginUser;
            } else {
                throw new ServiceException("登录失败！");
            }

        } finally {
            redisCache.releaseLock(lock, uuid);
        }
    }

    public LoginUser wxmaLoginTemporary(String appId, String code) {
        WxMaJscode2SessionResult jscode2session = null;
        try {
            jscode2session = WxMaConfig.getMaService(appId).jsCode2SessionInfo(code);
        } catch (WxErrorException e) {
            log.error("微信授权登录失败！{}", e.getMessage());
        }
        if (null == jscode2session) {
            throw new ServiceException("登录失败！");
        }
        LoginUser loginUser = new LoginUser();
        loginUser.setUserId("-1");
        loginUser.setUserInfo(new UserInfo());
        return loginUser;
    }

    public LoginUser wxmaloginByPhone(String appId, String code) {
        WxMaJscode2SessionResult jscode2session = null;
        String phoneNumber = null;
        try {
            WxMaService maService = WxMaConfig.getMaService(appId);
            jscode2session = maService.jsCode2SessionInfo(code);
            WxMaPhoneNumberInfo phoneNoInfo = maService.getUserService().getPhoneNumber(code);
            phoneNumber = phoneNoInfo.getPhoneNumber();
        } catch (WxErrorException e) {
            log.error("微信授权登录失败！{}", e.getMessage());
        }
        if (null == jscode2session) {
            throw new ServiceException("登录失败！");
        }

        String openId = jscode2session.getOpenid();
        String unionId = jscode2session.getUnionid();

        String uuid = UUID.randomUUID().toString();
        String lock = "lock:wxmaLoginByPhone:" + openId;
        try {
            if (redisCache.lockWait(lock, uuid)) {
                UmClientUser clientUser = clientUserMapper.selectOneByQuery(QueryWrapper.create().and(UM_CLIENT_USER.WXMA_OPENID.eq(openId).or(UM_CLIENT_USER.WX_UNIONID.eq(unionId))));

                if (null == clientUser) {
                    clientUser = new UmClientUser();
                    clientUser.setWxmaOpenid(openId);
                    clientUser.setWxUnionid(unionId);
                    clientUser.setPhone(phoneNumber);
                    clientUserMapper.insert(clientUser);
                } else {
                    clientUser.setPhone(phoneNumber);
                    clientUserMapper.update(clientUser);
                }

                LoginUser loginUser = new LoginUser();
                loginUser.setUserId(clientUser.getId());
                return loginUser;
            } else {
                throw new ServiceException("登录失败！");
            }

        } finally {
            redisCache.releaseLock(lock, uuid);
        }
    }
}
